/*
 * This program is free software; you can redistribute it and/or modify 
 * it under the terms of the GNU General Public License as published by 
 * the Free Software Foundation; either version 3 of the License, or 
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
 * for more details.
 * 
 * You should have received a copy of the GNU General Public License along 
 * with this program; if not, write to the Free Software Foundation, Inc., 
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#ifndef WISHMASTER_THREAD_H
#define WISHMASTER_THREAD_H

#include <vector>
#include <map>
#include <QObject>
#include <QString>
#include <QMutex>
#include <QDateTime>
#include <QBitArray>
#include "entitycollector.h"
#include "post.h"
#include "componentvisibility.h"
#include "threadptr.h"
#include "threadid.h"
#include "misc.h"

namespace Wishmaster
{
	class Board;

	class WISHMASTER_EXPORT Thread : public QObject
	{
		Q_OBJECT
	public:

		enum State
		{
			sNewThread = 1,
			sUpToDate = 2,
			sNewPosts = 3
		};

		enum ThreadFlag
		{
			Alive,
			Swapped,
			Watched,
			Archived,
			Responded,
			MaxThreadFlag = 32
		};

		Thread(const ThreadId& threadId, Board* parent);
		virtual ~Thread();

		ThreadId id() const;

		int getPostsCount() const;
		void setPostsCount(int count);
		int getActualPostsCount() const;

		PostPtr getOpPost();
		void appendPost(const PostPtr& post);
		PostPtr getPost(int number) const;
		PostPtr getPost(int number);
		PostPtr lookupPost(const PostId& id);
		PostPtr pickPost(const PostId& id);
		void clear();

		int getPostPosition(const PostId& id);
		PostId getPostByLink(const QString& link);

		PostId lastPostId() const;

		void setTimestamp(const QDateTime& ts);
		QDateTime getTimestamp() const;

		void setThreadTimestamp(const QDateTime& ts);
		QDateTime threadTimestamp() const;

		QString getShortName();
		QString getName();
		void setName(const QString& name);

		void setSortOrder(int order);
		int getSortOrder() const;

		void swap();
		void unswap();

		bool flag(ThreadFlag fl) const;
		void setFlag(ThreadFlag fl, bool value);

		ComponentVisibility visibility() const;
		void setVisibility(ComponentVisibility newVisibility);

		void hidePost(const PostId& id);
		bool isPostHidden(const PostId& id);

		QUrl leaderPicUrl() const;
		void setLeaderPicUrl(const QUrl& url);

		QImage leaderPic() const;
		void setLeaderPic(const QImage& image);

		int page() const;
		void setPage(int page);

		Board* parent() const {return m_parent;}
		
		State state();
		void setState(State s);

		typedef ThreadId IdType;

	protected:
		EntityCollector<PostPtr, PostId>* visiblePosts() const;
		typedef EntityCollector<PostPtr, PostId>::TVector::iterator postIterator;

		void doSwap();
		void doUnswap();

	private:
		PostPtr m_opPost;
		QString m_name;
		ThreadId m_threadId;
		mutable int m_postcount;

		bool m_hidden;
		ComponentVisibility m_visibility;

		QBitArray m_flags;
		State m_state;
		QMutex m_mutex;
		int m_sortOrder;
		QDateTime m_accessTimestamp;
		QDateTime m_threadTimestamp;
		Board* m_parent;
		QUrl m_leaderPicUrl;
		QImage m_leaderPic;
		EntityCollector<PostPtr, PostId>* m_visiblePosts;
		int m_page;
	};
}

#endif

